package com.christina.engine.response.decorator;

import com.christina.engine.response.model.ResponseContext;
import com.christina.engine.response.model.ResponseResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 响应装饰器抽象基类
 * 实现装饰器模式，为响应生成添加额外功能
 * 
 * @author Christina
 */
public abstract class ResponseDecorator implements ResponseGenerator {
    
    protected final Logger logger = LoggerFactory.getLogger(getClass());
    
    protected final ResponseGenerator wrapped;
    private final String decoratorName;
    private final int priority;
    private boolean enabled = true;
    
    protected ResponseDecorator(ResponseGenerator wrapped, String decoratorName, int priority) {
        this.wrapped = wrapped;
        this.decoratorName = decoratorName;
        this.priority = priority;
    }
    
    @Override
    public final ResponseResult generateResponse(ResponseContext context) {
        if (!isEnabled()) {
            logger.debug("Decorator {} is disabled, skipping decoration", getDecoratorName());
            return wrapped.generateResponse(context);
        }
        
        if (!shouldDecorate(context)) {
            logger.debug("Decorator {} skipping decoration for context", getDecoratorName());
            return wrapped.generateResponse(context);
        }
        
        logger.debug("Applying decorator: {}", getDecoratorName());
        long startTime = System.currentTimeMillis();
        
        try {
            // 前置处理
            preDecorate(context);
            
            // 调用被装饰的生成器
            ResponseResult result = wrapped.generateResponse(context);
            
            // 后置装饰
            ResponseResult decoratedResult = decorate(context, result);
            
            // 后置处理
            postDecorate(context, decoratedResult);
            
            long decorationTime = System.currentTimeMillis() - startTime;
            decoratedResult.addMetadata("decoration_" + getDecoratorName() + "_time_ms", decorationTime);
            
            logger.debug("Decorator {} applied successfully in {}ms", getDecoratorName(), decorationTime);
            
            return decoratedResult;
            
        } catch (Exception e) {
            logger.error("Error in decorator {}: {}", getDecoratorName(), e.getMessage(), e);
            return handleDecorationError(context, e);
        }
    }
    
    /**
     * 执行装饰逻辑
     * 子类必须实现此方法来定义具体的装饰行为
     * 
     * @param context 响应上下文
     * @param result 原始响应结果
     * @return 装饰后的响应结果
     */
    protected abstract ResponseResult decorate(ResponseContext context, ResponseResult result);
    
    /**
     * 装饰响应结果
     * 
     * @param result 原始响应结果
     * @param context 响应上下文
     * @return 装饰后的响应结果
     */
    public ResponseResult decorate(ResponseResult result, ResponseContext context) {
        if (!isEnabled()) {
            logger.debug("Decorator {} is disabled, returning original result", getDecoratorName());
            return result;
        }
        
        if (!shouldDecorate(context)) {
            logger.debug("Decorator {} skipping decoration for context", getDecoratorName());
            return result;
        }
        
        logger.debug("Applying decorator: {}", getDecoratorName());
        
        try {
            // 前置处理
            preDecorate(context);
            
            // 执行装饰逻辑
            ResponseResult decoratedResult = doDecorate(result, context);
            
            // 后置处理
            postDecorate(context, decoratedResult);
            
            return decoratedResult;
            
        } catch (Exception e) {
            logger.error("Error in decorator {}: {}", getDecoratorName(), e.getMessage(), e);
            return handleDecorationError(context, e);
        }
    }
    
    /**
     * 执行具体的装饰逻辑
     * 子类需要实现此方法
     * 
     * @param result 原始响应结果
     * @param context 响应上下文
     * @return 装饰后的响应结果
     */
    protected abstract ResponseResult doDecorate(ResponseResult result, ResponseContext context);
    
    /**
     * 判断是否应该对当前上下文进行装饰
     * 子类可以重写此方法来实现条件装饰
     * 
     * @param context 响应上下文
     * @return 是否应该装饰
     */
    protected boolean shouldDecorate(ResponseContext context) {
        return true; // 默认总是装饰
    }
    
    /**
     * 前置处理钩子方法
     * 在调用被装饰的生成器之前执行
     * 
     * @param context 响应上下文
     */
    protected void preDecorate(ResponseContext context) {
        // 默认实现为空，子类可以重写
    }
    
    /**
     * 后置处理钩子方法
     * 在装饰完成后执行
     * 
     * @param context 响应上下文
     * @param result 装饰后的响应结果
     */
    protected void postDecorate(ResponseContext context, ResponseResult result) {
        // 默认实现为空，子类可以重写
    }
    
    /**
     * 处理装饰过程中的错误
     * 
     * @param context 响应上下文
     * @param exception 发生的异常
     * @return 错误处理后的响应结果
     */
    protected ResponseResult handleDecorationError(ResponseContext context, Exception exception) {
        logger.warn("Decoration failed, returning original result from wrapped generator");
        
        try {
            // 尝试返回原始生成器的结果
            return wrapped.generateResponse(context);
        } catch (Exception e) {
            logger.error("Wrapped generator also failed", e);
            return ResponseResult.failure(
                    "响应生成失败: " + exception.getMessage(),
                    getDecoratorName()
            );
        }
    }
    
    @Override
    public String getName() {
        return getDecoratorName() + "(" + wrapped.getName() + ")";
    }
    
    @Override
    public boolean supports(String responseType) {
        return wrapped.supports(responseType);
    }
    
    /**
     * 获取装饰器名称
     * 
     * @return 装饰器名称
     */
    public String getDecoratorName() {
        return decoratorName;
    }
    
    /**
     * 获取装饰器优先级
     * 优先级数值越小，优先级越高
     * 
     * @return 优先级
     */
    public int getPriority() {
        return priority;
    }
    
    /**
     * 检查装饰器是否启用
     * 
     * @return 是否启用
     */
    public boolean isEnabled() {
        return enabled;
    }
    
    /**
     * 设置装饰器启用状态
     * 
     * @param enabled 是否启用
     */
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }
    
    /**
     * 获取被装饰的生成器
     * 
     * @return 被装饰的生成器
     */
    public ResponseGenerator getWrapped() {
        return wrapped;
    }
    
    /**
     * 创建装饰器链的便利方法
     * 
     * @param generator 基础生成器
     * @param decorators 装饰器数组
     * @return 装饰后的生成器
     */
    public static ResponseGenerator chain(ResponseGenerator generator, ResponseDecorator... decorators) {
        ResponseGenerator current = generator;
        
        // 按优先级排序装饰器
        java.util.Arrays.sort(decorators, java.util.Comparator.comparingInt(ResponseDecorator::getPriority));
        
        for (ResponseDecorator decorator : decorators) {
            // 创建新的装饰器实例来包装当前生成器
            current = createDecoratorInstance(decorator, current);
        }
        
        return current;
    }
    
    /**
     * 创建装饰器实例的辅助方法
     * 
     * @param template 装饰器模板
     * @param generator 要包装的生成器
     * @return 新的装饰器实例
     */
    private static ResponseGenerator createDecoratorInstance(ResponseDecorator template, ResponseGenerator generator) {
        // 这里需要根据具体的装饰器类型来创建实例
        // 由于Java的限制，这里使用反射或者工厂方法
        try {
            return template.getClass()
                    .getDeclaredConstructor(ResponseGenerator.class)
                    .newInstance(generator);
        } catch (Exception e) {
            throw new RuntimeException("Failed to create decorator instance", e);
        }
    }
}